<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>工程中心脑功能检测与调控平台 - 交互式预约日历</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Chosen Palette: Warm Neutrals -->
    <!-- Application Structure Plan: The application is now a full-stack, real-time collaborative SPA. It uses Firestore as a backend database to store and sync appointment data. All users see the same data, and updates are reflected live for everyone. The frontend structure remains a highly usable calendar-dashboard, but the data source is switched from a local variable to a live Firestore connection. This makes it a true multi-user application. -->
    <!-- Visualization & Content Choices: Report Info: Collaborative appointment data -> Goal: Organize/Inform/Synthesize/Edit/Navigate/Collaborate -> Viz/Presentation Method: All previous UI elements are retained, but now powered by real-time data from Firestore. A loading state is added. -> Interaction: All previous interactions are retained. The key change is that the "Save Appointment" action now writes data to Firestore, which then automatically triggers a UI update for all connected clients via an onSnapshot listener. -> Justification: This is the critical evolution from a demo to a functional tool. By integrating a backend database, it solves the problem of data persistence and multi-user synchronization, making it a viable collaborative scheduling application. -> Library/Method: Vanilla JavaScript, Tailwind CSS, Fetch API for Gemini, and now the Firebase JS SDK for database operations. -->
    <!-- CONFIRMATION: NO SVG graphics used. NO Mermaid JS used. -->
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
        }
        .calendar-day:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 10px rgba(0,0,0,0.1);
        }
        .gemini-output {
            white-space: pre-wrap;
            line-height: 1.7;
        }
        .loader {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #3498db;
            border-radius: 50%;
            width: 30px;
            height: 30px;
            animation: spin 1s linear infinite;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .month-picker-button:hover {
            background-color: #0d9488; /* darker teal */
            color: white;
        }
    </style>
</head>
<body class="bg-stone-50 text-stone-800">

    <div class="container mx-auto p-4 md:p-8 max-w-7xl">

        <header class="text-center mb-8">
            <h1 class="text-3xl md:text-4xl font-bold text-stone-900">工程中心脑功能检测与调控平台</h1>
            <p class="text-stone-600 mt-2">交互式预约日历 (实时协作版)</p>
        </header>

        <div id="info-section" class="bg-white p-6 rounded-lg shadow-md mb-8">
            <div class="flex justify-between items-center cursor-pointer" id="info-header">
                <h2 class="text-xl font-semibold text-stone-800">平台使用说明及联系方式</h2>
                <svg id="info-arrow" class="w-6 h-6 text-stone-600 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
            </div>
            <div id="info-content" class="hidden mt-4 text-stone-700 space-y-2">
                <p><strong>① 运营时间：</strong>本平台运营时间为9：00-16：00，运营时间外请咨询管理员。</p>
                <p><strong>② 预约登记：</strong>请在对应使用日期登记预约人姓名、手机号、单位（空间不够可加行）。如不使用，请及时取消预约。</p>
                <p><strong>③ 操作培训：</strong>如需操作培训，请联系管理员。</p>
                <p><strong>管理员联系方式 (微信号)：</strong></p>
                <ul class="list-disc list-inside ml-4">
                    <li>蒋奕晨：jiangyichen-1002</li>
                    <li>朱光跃：Hy340703</li>
                    <li>毛梦钗：Echo_Meow</li>
                </ul>
            </div>
        </div>

        <main class="bg-white p-4 sm:p-6 rounded-lg shadow-lg">
            <div class="flex flex-col sm:flex-row items-center justify-between mb-6 gap-4">
                <div class="flex items-center justify-center">
                    <button id="prev-month" class="p-2 rounded-full hover:bg-stone-100 transition-colors">
                        <svg class="w-6 h-6 text-stone-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
                    </button>
                    <h2 id="current-month-year" class="text-2xl font-semibold text-stone-800 w-48 text-center cursor-pointer hover:text-teal-600 transition-colors" title="点击选择月份"></h2>
                    <button id="next-month" class="p-2 rounded-full hover:bg-stone-100 transition-colors">
                        <svg class="w-6 h-6 text-stone-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
                    </button>
                </div>
                <button id="summarize-month" class="flex items-center gap-2 bg-teal-500 text-white font-semibold py-2 px-4 rounded-lg hover:bg-teal-600 transition-colors shadow">
                    ✨ 月度智能总结
                </button>
            </div>

            <div id="summary-container" class="mb-6 p-4 border-l-4 border-teal-400 bg-teal-50 rounded-r-lg hidden">
                <h3 class="font-semibold text-teal-800 mb-2">本月总结</h3>
                <div id="summary-output" class="text-teal-900 gemini-output"></div>
            </div>
            
            <div id="calendar-view">
                <div id="calendar-weekdays" class="grid grid-cols-7 gap-2 text-center font-medium text-stone-500 mb-2">
                    <div>一</div><div>二</div><div>三</div><div>四</div><div>五</div><div class="text-amber-600">六</div><div class="text-amber-600">日</div>
                </div>
                <div id="calendar-grid" class="grid grid-cols-7 gap-2"></div>
                 <div id="loading-indicator" class="flex justify-center items-center p-8"><div class="loader"></div></div>
            </div>

            <div id="month-picker-view" class="hidden">
                 <div class="flex items-center justify-between mb-6">
                    <button id="picker-prev-year" class="p-2 rounded-full hover:bg-stone-100 transition-colors">
                        <svg class="w-6 h-6 text-stone-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
                    </button>
                    <h2 id="picker-current-year" class="text-2xl font-semibold text-stone-800"></h2>
                    <button id="picker-next-year" class="p-2 rounded-full hover:bg-stone-100 transition-colors">
                        <svg class="w-6 h-6 text-stone-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
                    </button>
                </div>
                <div id="month-picker-grid" class="grid grid-cols-3 md:grid-cols-4 gap-4"></div>
            </div>
        </main>

    </div>

    <div id="details-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 transition-opacity duration-300 opacity-0 pointer-events-none">
        <div id="modal-content" class="bg-white rounded-lg shadow-xl w-full max-w-md p-6 transform scale-95 transition-transform duration-300">
            <div class="flex justify-between items-center mb-4">
                <h3 id="modal-date" class="text-xl font-semibold text-stone-800"></h3>
                <button id="close-modal" class="text-stone-500 hover:text-stone-800">
                    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
                </button>
            </div>
            <div id="modal-body" class="space-y-4 max-h-[60vh] overflow-y-auto"></div>
        </div>
    </div>
    
    <script type="module">
        import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js";
        import { getAuth, signInAnonymously, signInWithCustomToken } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-auth.js";
        import { getFirestore, doc, onSnapshot, setDoc, getDoc } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-firestore.js";

        let db;
        let auth;
        let unsubscribe; // To detach Firestore listener
        let currentMonthData = {};

        const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-calendar-app';
        
        async function initializeFirebase() {
            try {
                const firebaseConfig = JSON.parse(typeof __firebase_config !== 'undefined' ? __firebase_config : '{}');
                const app = initializeApp(firebaseConfig);
                db = getFirestore(app);
                auth = getAuth(app);

                if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) {
                    await signInWithCustomToken(auth, __initial_auth_token);
                } else {
                    await signInAnonymously(auth);
                }
                console.log("Firebase initialized and user signed in.");
                setupRealtimeListener();
            } catch (error) {
                console.error("Firebase initialization failed:", error);
                document.getElementById('loading-indicator').innerHTML = `<p class="text-red-500">无法连接到数据库，请刷新页面重试。</p>`;
            }
        }
        
        function setupRealtimeListener() {
            const year = currentDate.getFullYear();
            const month = String(currentDate.getMonth() + 1).padStart(2, '0');
            const docId = `${year}-${month}`;
            const docRef = doc(db, "artifacts", appId, "public/data/appointments", docId);

            if (unsubscribe) {
                unsubscribe();
            }

            document.getElementById('loading-indicator').style.display = 'flex';
            calendarGrid.style.display = 'none';

            unsubscribe = onSnapshot(docRef, (doc) => {
                currentMonthData = doc.exists() ? doc.data() : {};
                renderCalendar();
                document.getElementById('loading-indicator').style.display = 'none';
                calendarGrid.style.display = 'grid';
            }, (error) => {
                console.error("Error listening to document:", error);
                document.getElementById('loading-indicator').innerHTML = `<p class="text-red-500">无法获取实时数据。</p>`;
            });
        }


        let currentDate = new Date();
        let pickerDate = new Date();

        const calendarGrid = document.getElementById('calendar-grid');
        const currentMonthYear = document.getElementById('current-month-year');
        const prevMonthBtn = document.getElementById('prev-month');
        const nextMonthBtn = document.getElementById('next-month');
        const modal = document.getElementById('details-modal');
        const modalContent = document.getElementById('modal-content');
        const closeModalBtn = document.getElementById('close-modal');
        const modalDate = document.getElementById('modal-date');
        const modalBody = document.getElementById('modal-body');
        const summarizeBtn = document.getElementById('summarize-month');
        const summaryContainer = document.getElementById('summary-container');
        const summaryOutput = document.getElementById('summary-output');

        const calendarView = document.getElementById('calendar-view');
        const monthPickerView = document.getElementById('month-picker-view');
        const pickerCurrentYear = document.getElementById('picker-current-year');
        const pickerPrevYearBtn = document.getElementById('picker-prev-year');
        const pickerNextYearBtn = document.getElementById('picker-next-year');
        const monthPickerGrid = document.getElementById('month-picker-grid');

        async function callGeminiAPI(prompt, targetElement) {
            targetElement.innerHTML = '<div class="flex justify-center items-center"><div class="loader"></div></div>';
            const apiKey = "";
            const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`;
            try {
                const payload = { contents: [{ parts: [{ text: prompt }] }] };
                const response = await fetch(apiUrl, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(payload)
                });
                if (!response.ok) { throw new Error(`API 请求失败，状态码：${response.status}`); }
                const result = await response.json();
                const text = result.candidates?.[0]?.content?.parts?.[0]?.text;
                if (text) { targetElement.innerHTML = text; } 
                else { throw new Error('未能从 API 响应中提取文本。'); }
            } catch (error) {
                console.error("Gemini API 调用出错:", error);
                targetElement.innerHTML = `<p class="text-red-500">智能服务暂不可用，请稍后再试。</p>`;
            }
        }
        
        summarizeBtn.addEventListener('click', () => {
            if (Object.keys(currentMonthData).length === 0) {
                summaryOutput.innerHTML = '本月没有预约记录。';
                summaryContainer.classList.remove('hidden');
                return;
            }
            let bookingDetails = '';
            const year = currentDate.getFullYear();
            const month = currentDate.getMonth() + 1;
            for (const day in currentMonthData) {
                currentMonthData[day].forEach(b => {
                    bookingDetails += `日期: ${year}-${month}-${day}, 预约人: ${b.name}, 时间: ${b.time}, 单位: ${b.org}\n`;
                });
            }
            const prompt = `你是一位数据分析助理。请根据以下${year}年${month}月的预约数据，对本月的预约情况进行一个简短的总结分析（2-3句话）。请重点指出总预约次数、最繁忙的日期或时段（如果有规律的话），以及主要的预约单位。请以友好的口吻进行总结。数据如下：\n${bookingDetails}`;
            summaryContainer.classList.remove('hidden');
            callGeminiAPI(prompt, summaryOutput);
        });

        function renderCalendar() {
            calendarGrid.innerHTML = '';
            summaryContainer.classList.add('hidden');
            const year = currentDate.getFullYear();
            const month = currentDate.getMonth();
            currentMonthYear.textContent = `${year}年 ${month + 1}月`;
            const firstDayOfMonth = new Date(year, month, 1).getDay();
            const daysInMonth = new Date(year, month + 1, 0).getDate();
            let dayOffset = firstDayOfMonth === 0 ? 6 : firstDayOfMonth - 1;
            for (let i = 0; i < dayOffset; i++) { calendarGrid.appendChild(document.createElement('div')); }
            for (let day = 1; day <= daysInMonth; day++) {
                const dayEl = document.createElement('div');
                dayEl.className = 'calendar-day relative p-2 h-20 md:h-28 border rounded-md cursor-pointer transition-all duration-200';
                const dayNumber = document.createElement('span');
                dayNumber.textContent = day;
                dayNumber.className = 'text-sm';
                dayEl.appendChild(dayNumber);
                const today = new Date();
                if (year === today.getFullYear() && month === today.getMonth() && day === today.getDate()) {
                    dayEl.classList.add('bg-amber-100', 'text-amber-800', 'font-bold');
                } else {
                    dayEl.classList.add('bg-stone-100/50', 'hover:bg-teal-50');
                }
                const dayKey = String(day).padStart(2, '0');
                if (currentMonthData[dayKey] && currentMonthData[dayKey].length > 0) {
                    dayEl.classList.add('bg-teal-100');
                    const dot = document.createElement('div');
                    dot.className = 'absolute bottom-2 right-2 w-2 h-2 bg-teal-500 rounded-full';
                    dayEl.appendChild(dot);
                }
                dayEl.addEventListener('click', () => showDetails(year, month, day));
                calendarGrid.appendChild(dayEl);
            }
        }
        
        function renderMonthPicker() {
            monthPickerGrid.innerHTML = '';
            const year = pickerDate.getFullYear();
            pickerCurrentYear.textContent = `${year}年`;
            for (let i = 0; i < 12; i++) {
                const monthButton = document.createElement('button');
                monthButton.textContent = `${i + 1}月`;
                monthButton.className = 'month-picker-button p-4 rounded-lg bg-teal-500/10 text-teal-700 font-semibold transition-colors duration-200';
                monthButton.dataset.month = i;
                monthButton.addEventListener('click', () => {
                    currentDate = new Date(year, i, 1);
                    toggleCalendarView(true);
                    setupRealtimeListener();
                });
                monthPickerGrid.appendChild(monthButton);
            }
        }

        function toggleCalendarView(showCalendar) {
            if(showCalendar) {
                calendarView.classList.remove('hidden');
                monthPickerView.classList.add('hidden');
            } else {
                calendarView.classList.add('hidden');
                monthPickerView.classList.remove('hidden');
                pickerDate = new Date(currentDate);
                renderMonthPicker();
            }
        }

        async function showDetails(year, month, day) {
            modalDate.textContent = `${year}年 ${month + 1}月 ${day}日`;
            modalBody.innerHTML = '';
            const dayKey = String(day).padStart(2, '0');
            const bookings = currentMonthData[dayKey] || [];
            
            if (bookings.length > 0) {
                bookings.forEach((booking, index) => {
                    const bookingWrapper = document.createElement('div');
                    bookingWrapper.className = 'p-3 bg-stone-50 rounded-md border space-y-3';
                    let content = `<p class="font-semibold text-stone-700">${booking.name}</p>`;
                    if(booking.time) content += `<p class="text-sm text-stone-600">时间：${booking.time}</p>`;
                    if(booking.org) content += `<p class="text-sm text-stone-500">单位：${booking.org}</p>`;
                    const reminderBtn = `<button class="generate-reminder-btn text-sm bg-sky-500 text-white py-1 px-3 rounded-md hover:bg-sky-600 transition-colors" data-booking-index="${index}">✨ 生成提醒</button>`;
                    const reminderOutputId = `reminder-output-${year}-${month}-${day}-${index}`;
                    const reminderOutput = `<div id="${reminderOutputId}" class="hidden mt-2 p-2 bg-sky-50 border-l-2 border-sky-400 text-sm text-sky-800 rounded-r-md gemini-output"></div>`;
                    bookingWrapper.innerHTML = content + reminderBtn + reminderOutput;
                    modalBody.appendChild(bookingWrapper);
                });
            } else {
                modalBody.innerHTML = '<p class="text-stone-500 text-center py-4">当日无预约记录。</p>';
            }

            const addAppointmentSection = document.createElement('div');
            addAppointmentSection.className = 'mt-6 pt-4 border-t';
            addAppointmentSection.innerHTML = `
                <h4 class="font-semibold text-lg mb-3">添加新预约</h4>
                <div class="space-y-3">
                    <div>
                        <label for="newName" class="text-sm font-medium text-stone-600">姓名/联系方式</label>
                        <input type="text" id="newName" class="mt-1 w-full p-2 border rounded-md focus:ring-2 focus:ring-teal-500 focus:border-teal-500" placeholder="必填">
                    </div>
                    <div>
                        <label for="newTime" class="text-sm font-medium text-stone-600">预计使用时间</label>
                        <input type="text" id="newTime" class="mt-1 w-full p-2 border rounded-md focus:ring-2 focus:ring-teal-500 focus:border-teal-500" placeholder="例如: 9:00-12:00">
                    </div>
                    <div>
                        <label for="newOrg" class="text-sm font-medium text-stone-600">单位</label>
                        <input type="text" id="newOrg" class="mt-1 w-full p-2 border rounded-md focus:ring-2 focus:ring-teal-500 focus:border-teal-500">
                    </div>
                    <button id="save-booking-btn" class="w-full bg-teal-500 text-white font-semibold py-2 px-4 rounded-lg hover:bg-teal-600 transition-colors shadow">保存预约</button>
                </div>
            `;
            modalBody.appendChild(addAppointmentSection);

            document.getElementById('save-booking-btn').addEventListener('click', async () => {
                const newName = document.getElementById('newName').value;
                const newTime = document.getElementById('newTime').value;
                const newOrg = document.getElementById('newOrg').value;
                if (!newName.trim()) { alert('“姓名/联系方式”为必填项。'); return; }
                const newBooking = { name: newName, time: newTime, org: newOrg };
                
                const docId = `${year}-${String(month + 1).padStart(2, '0')}`;
                const docRef = doc(db, "artifacts", appId, "public/data/appointments", docId);

                const updatedDayBookings = [...bookings, newBooking];
                
                try {
                    await setDoc(docRef, { [dayKey]: updatedDayBookings }, { merge: true });
                    hideDetails(); 
                } catch (error) {
                    console.error("Error saving booking: ", error);
                    alert("保存失败，请检查网络后重试。");
                }
            });

            document.querySelectorAll('.generate-reminder-btn').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    const bookingIndex = e.target.dataset.bookingIndex;
                    const selectedBooking = bookings[bookingIndex];
                    const reminderOutputEl = document.getElementById(`reminder-output-${year}-${month}-${day}-${bookingIndex}`);
                    reminderOutputEl.classList.remove('hidden');
                    const prompt = `你是一位专业的行政助理。请根据以下信息，为 ${selectedBooking.name} 生成一条礼貌、简洁的预约提醒短信，以便复制发送。信息如下：\n日期：${year}年${month + 1}月${day}日\n时间：${selectedBooking.time || '未指定'}\n单位：${selectedBooking.org || '未指定'}\n地点：工程中心脑功能检测与调控平台`;
                    callGeminiAPI(prompt, reminderOutputEl);
                });
            });

            modal.classList.remove('opacity-0', 'pointer-events-none');
            modalContent.classList.remove('scale-95');
        }

        function hideDetails() {
            modal.classList.add('opacity-0', 'pointer-events-none');
            modalContent.classList.add('scale-95');
        }

        prevMonthBtn.addEventListener('click', () => {
            currentDate.setMonth(currentDate.getMonth() - 1);
            setupRealtimeListener();
        });

        nextMonthBtn.addEventListener('click', () => {
            currentDate.setMonth(currentDate.getMonth() + 1);
            setupRealtimeListener();
        });

        closeModalBtn.addEventListener('click', hideDetails);
        modal.addEventListener('click', (e) => { if (e.target === modal) hideDetails(); });
        
        currentMonthYear.addEventListener('click', () => toggleCalendarView(monthPickerView.classList.contains('hidden') ? false : true));
        pickerPrevYearBtn.addEventListener('click', () => {
            pickerDate.setFullYear(pickerDate.getFullYear() - 1);
            renderMonthPicker();
        });
        pickerNextYearBtn.addEventListener('click', () => {
            pickerDate.setFullYear(pickerDate.getFullYear() + 1);
            renderMonthPicker();
        });

        function toggleInfo() {
            document.getElementById('info-content').classList.toggle('hidden');
            document.getElementById('info-arrow').classList.toggle('rotate-180');
        }
        
        document.getElementById('info-header').addEventListener('click', toggleInfo);
        document.addEventListener('DOMContentLoaded', initializeFirebase);
    </script>
</body>
</html>

